package com.sinodata.bsm.cicp.collector.environment;

import org.apache.log4j.Logger;

import com.sinodata.bsm.cicp.exception.CollectorException;

/**
 *
 * @author 友联创新 hehy
 * @date Dec 19, 2008
 */
public class EmersonDM3000 {
    static Logger logger = Logger.getLogger(EmersonDM3000.class);

    /**
     * 获取设备地址命令 此命令只能适用于点到点的通信方式
     *
     * @return
     * @throws CollectorException
     */
    public static byte[] getAdrCmd() throws CollectorException {
        byte VER = 0x0;// 通信协议版本号
        byte ADR = 0x0;// 设备地址描述（1～254，0、255保留）
        byte CID1 = 0x60;// 控制标识码（设备类型描述）
        byte CID2 = 0x50;// 命令信息:控制标识码（数据或动作类型描述） 响应信息:返回码RTN
        byte[] cmd = null;
        cmd = ElectriProtocol.getCommand(VER, ADR, CID1, CID2, null);
        return cmd;
    }

    /**
     * 解析获取设备地址命令命令返回
     *
     * @param resp
     * @return
     */
    public static byte analyseAdrResponse(byte[] resp) {
        return ElectriProtocol.unite2ASCII(resp[3], resp[4]);
    }

    /**
     * 获取通信协议版本号
     *
     * @return
     * @throws CollectorException
     */
    public static byte[] getverCmd() throws CollectorException {
        byte VER = 0x0;// 通信协议版本号
        byte ADR = 0x0;// 设备地址描述（1～254，0、255保留）
        byte CID1 = 0x60;// 控制标识码（设备类型描述）
        byte CID2 = 0x4F;// 命令信息:控制标识码（数据或动作类型描述） 响应信息:返回码RTN
        byte[] cmd = ElectriProtocol.getCommand(VER, ADR, CID1, CID2, null);
        return cmd;
    }

    /**
     *获取通信协议版本号
     * @param resp
     * @return
     */
    public byte analyseVerResponse(byte[] resp) {
        return ElectriProtocol.unite2ASCII(resp[1], resp[2]);
    }

    /**
    * 检查命令返回的CID2信息
    * @param CID2
    * @return
    * @throws Exception
    */
    public static boolean chkCID2RTN(byte CID2) throws Exception {
        switch (CID2) {
            case 0x00:
                return true;
            case 0x01:
                throw new Exception("命令的VER错误");
            case 0x02:
                throw new Exception("CHKSUM错");
            case 0x03:
                throw new Exception("LCHKSUM错");
            case 0x04:
                throw new Exception("CID2无效");
            case 0x05:
                throw new Exception("命令格式错");
            case 0x06:
                throw new Exception("无效数据");
            default:
                throw new Exception("其他错误");
        }
    }

    /**
     * 获取模拟量量化后数据命令（定点数）
     * @throws CollectorException
     */
    public static byte[] analogSignalsCmd(byte ver, byte adr) throws CollectorException {
        byte VER = ver;// 通信协议版本号
        byte ADR = adr;// 设备地址描述（1～254，0、255保留）
        byte CID1 = 0x60;// 控制标识码（设备类型描述）
        byte CID2 = 0x42;// 命令信息:控制标识码（数据或动作类型描述） 响应信息:返回码RTN
        byte[] cmd = ElectriProtocol.getCommand(VER, ADR, CID1, CID2, null);
        return cmd;
    }

    /**
     * 分析获取模拟量量化后数据命令返回
     * @throws CollectorException
     */
    public static int[] analyseAnalogSignalsResponse(byte[] resp) throws CollectorException {
        byte[] infoBytes = ElectriProtocol.getInfoBytes(resp);
        if (infoBytes.length != 6) {
            logger.error("模拟量量化后数据命令返回格式不正确");
            return null;
        }
        // 室内温度
        int temperatureRoom = ElectriProtocol.mergeInt(infoBytes[0], infoBytes[1]);
        // 室内湿度
        int humidityRoom = ElectriProtocol.mergeInt(infoBytes[2], infoBytes[3]);
        // 室外温度
        int temperatureOutRoom = ElectriProtocol.mergeInt(infoBytes[4], infoBytes[5]);
        return new int[] { temperatureRoom, humidityRoom, temperatureOutRoom };
    }

    /**
     * 获取开关输入状态
     *
     * @param adr
     * @return
     * @throws CollectorException
     */
    public static byte[] switchStatusCmd(byte ver, byte adr) throws CollectorException {
        byte VER = ver;// 通信协议版本号
        byte ADR = adr;// 设备地址描述（1～254，0、255保留）
        byte CID1 = 0x60;// 控制标识码（设备类型描述）
        byte CID2 = 0x43;// 命令信息:控制标识码（数据或动作类型描述） 响应信息:返回码RTN
        byte[] cmd = ElectriProtocol.getCommand(VER, ADR, CID1, CID2, null);
        return cmd;
    }

    /**
     * 分析开关量返回
     *
     * @param resp
     * @return
     * @throws CollectorException
     */
    public static Boolean analyseSwitchResponse(byte[] resp) throws CollectorException {
        boolean runState = false;
        byte[] infoBytes = ElectriProtocol.getInfoBytes(resp);
        if (infoBytes.length != 2) {
            logger.error("开关输入状态返回格式不正确");
            return false;
        }
        if (infoBytes[0] == (byte) 0x01) {
            runState = true;
        }
        return runState;
    }

    /**
     * 获取系统参数（定点数）命令
     * @param ver
     * @param adr
     * @return
     * @throws CollectorException
     */
    public static byte[] sysParamCmd(byte ver, byte adr) throws CollectorException {
        byte VER = ver;// 通信协议版本号
        byte ADR = adr;// 设备地址描述（1～254，0、255保留）
        byte CID1 = 0x60;// 控制标识码（设备类型描述）
        byte CID2 = 0x47;// 命令信息:控制标识码（数据或动作类型描述） 响应信息:返回码RTN
        byte[] cmd = ElectriProtocol.getCommand(VER, ADR, CID1, CID2, null);
        return cmd;
    }

    /**
     * 分析获取系统参数（定点数）命令
     *
     * @param resp
     * @return
     * @throws CollectorException
     */
    public static int[] analyseSysParamCmd(byte[] resp) throws CollectorException {
        byte[] infoBytes = ElectriProtocol.getInfoBytes(resp);
        if (infoBytes.length != 13) {
            logger.error("分析获取系统参数（定点数）命令返回格式不正确");
            return null;
        }
        // 温度设定点
        int temperature = ElectriProtocol.mergeInt(infoBytes[4], infoBytes[5]);
        // 湿度设定点
        int humidity = ElectriProtocol.mergeInt(infoBytes[8], infoBytes[9]);
        return new int[] { temperature, humidity };
    }

    /**
     * 获取报警状态
     *
     * @param ver
     * @param adr
     * @return
     * @throws CollectorException
     */
    public static byte[] alarmCmd(byte ver, byte adr) throws CollectorException {
        byte VER = ver;// 通信协议版本号
        byte ADR = adr;// 设备地址描述（1～254，0、255保留）
        byte CID1 = 0x60;// 控制标识码（设备类型描述）
        byte CID2 = (byte) 0x80;// 命令信息:控制标识码（数据或动作类型描述） 响应信息:返回码RTN
        byte[] info = new byte[] { 0x01 };
        byte[] cmd = ElectriProtocol.getCommand(VER, ADR, CID1, CID2, info);
        return cmd;
    }

    /**
     * 解析报警命令返回
     *
     * @param resp
     * @return
     * @throws CollectorException
     */
    public static String[] analyseAlarmResponse(byte[] resp) throws CollectorException {
        byte[] infoBytes = ElectriProtocol.getInfoBytes(resp);
        if (infoBytes.length != 6) {
            logger.error("报警状态返回格式不正确");
            return null;
        }
        String[] ret = new String[] { "", "" };
        switch (infoBytes[0]) {
            case 0x01:
                ret[0] = "高压报警";
                break;
            case 0x02:
                ret[0] = "低压报警";
                break;
            case 0x03:
                ret[0] = "高温报警";
                break;
            case 0x04:
                ret[0] = "低温报警";
                break;
            case 0x05:
                ret[0] = "高湿报警";
                break;
            case 0x06:
                ret[0] = "低湿报警";
                break;
            case 0x07:
                ret[0] = "电源故障报警";
                break;
            case 0x08:
                ret[0] = "短周期报警";
                break;
            case 0x09:
                ret[0] = "用户自定义1报警";
                break;
            case 0x0A:
                ret[0] = "用户自定义2报警";
                break;
            case 0x0B:
                ret[0] = "主风机维护报警";
                break;
            case 0x0c:
                ret[0] = "加湿罐维护报警";
                break;
            case 0x0d:
                ret[0] = "过滤网维护报警";
                break;
            case 0x0e:
                ret[0] = "通讯故障报警";
                break;
            case 0x0f:
                ret[0] = "盘管冻结报警";
                break;
            case 0x10:
                ret[0] = "加湿器故障报警";
                break;
            default:
                break;
        }
        ret[1] = infoBytes[1] + "月" + infoBytes[2] + "日 " + infoBytes[3] + ":" + infoBytes[4];
        return ret;
    }

    public static void main(String[] args) {
        /*        byte[] bytes = null;
                try {
                    bytes = EmersonDM3000.analogSignalsCmd((byte) 0x21, (byte) 0x1);
                } catch (CollectorException e) {
                    e.printStackTrace();
                }
                for (int i = 0; i < bytes.length; i++) {
                    System.out.println("第" + (i + 1) + "byte:" + (char) (bytes[i]));
                }
                for (int i = 0; i < bytes.length; i++) {
                    System.out.print((char) (bytes[i]));
                }

                try {
                    System.out.println(EmersonDM3000.analyseAlarmResponse(new String("~21016000400C000000000000FB5F\r").getBytes()));
                } catch (CollectorException e) {
                    e.printStackTrace();
                }*/

    }

}
